package info.emamian.droplet.aws;

import java.util.List;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClient;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
import com.amazonaws.services.sqs.model.DeleteMessageRequest;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
import com.amazonaws.services.sqs.model.SendMessageRequest;

@Component
public class SQSService {
	private static final Logger logger = LoggerFactory.getLogger(SQSService.class);
	private AmazonSQS sqs = null;
	private static final String DEFAULT_QUEUE_NAME = "myInputQueue-" + System.getProperty("version");
	private String queueUrl;

	public SQSService() throws Exception {

		// if (queueUrl == null || queueUrl.trim().isEmpty()) { throw new
		// Exception(
		// "Queue url cannot be empty for SQS service"); }

		sqs = new AmazonSQSClient(new ClasspathPropertiesFileCredentialsProvider("AwsCredentials.properties"));
		Region usWest2 = Region.getRegion(Regions.US_WEST_2);
		sqs.setRegion(usWest2);
		try {
			if (!queueExist(queueUrl)) {
				queueUrl = createQueue(DEFAULT_QUEUE_NAME);
			}
		}
		catch (AmazonServiceException ase) {
			logger.error("Caught an AmazonServiceException, which means your request made it "
					+ "to Amazon SQS, but was rejected with an error response for some reason.");
			logger.error("Error Message:    " + ase.getMessage());
			logger.error("HTTP Status Code: " + ase.getStatusCode());
			logger.error("AWS Error Code:   " + ase.getErrorCode());
			logger.error("Error Type:       " + ase.getErrorType());
			logger.error("Request ID:       " + ase.getRequestId());
			logger.error("Exception", ase);
		}
		catch (AmazonClientException ace) {
			logger.error("Caught an AmazonClientException, which means the client encountered "
					+ "a serious internal problem while trying to communicate with SQS, such as not "
					+ "being able to access the network.");
			logger.error("Error Message: " + ace.getMessage());
			logger.error("Exception:", ace);
		}
	}

	public void deleteMessage(Message message) {
		// Delete a message
		logger.debug("Deleting a message.");
		if (message == null) {
			logger.debug("input message for deleting was null");
		}
		String messageRecieptHandle = message.getReceiptHandle();
		sqs.deleteMessage(new DeleteMessageRequest(queueUrl, messageRecieptHandle));
	}

	public static void debugMessage(Message message) {
		if (logger.isDebugEnabled()) {
			logger.debug("  Message");
			logger.debug("    MessageId:     " + message.getMessageId());
			logger.debug("    ReceiptHandle: " + message.getReceiptHandle());
			logger.debug("    MD5OfBody:     " + message.getMD5OfBody());
			logger.debug("    Body:          " + message.getBody());
			for (Entry<String, String> entry : message.getAttributes().entrySet()) {
				logger.debug("  Attribute");
				logger.debug("    Name:  " + entry.getKey());
				logger.debug("    Value: " + entry.getValue());
			}
		}
	}

	private boolean queueExist(String qUrl) {
		// List queues
		boolean ret = false;
		if (qUrl == null || qUrl.trim().isEmpty()) {
			logger.debug("queueExist: qUrl was empty");
		}

		logger.debug("Listing all queues in your account. Looking for {}", qUrl);
		for (String url : sqs.listQueues().getQueueUrls()) {
			logger.debug("  QueueUrl: " + url);
			if (url.equals(qUrl)) {
				logger.info("Queue found: {}", qUrl);
				ret = true;
			}
		}

		if (!ret) {
			logger.info("Queue '{}' not found", qUrl);
		}
		return ret;
	}

	private void ListQueues() {
		logger.debug("Listing all queues in your account.");
		for (String url : sqs.listQueues().getQueueUrls()) {
			logger.debug("  QueueUrl: " + url);
		}
	}

	private String createQueue(String qname) {
		// Create a queue
		logger.debug("Creating a new SQS queue called '{}'.", qname);
		CreateQueueRequest createQueueRequest = new CreateQueueRequest(qname);
		String queueUrl = sqs.createQueue(createQueueRequest).getQueueUrl();
		ListQueues();
		return queueUrl;
	}

	public void sendMessage(String msg, String queueUrl) {
		// Send a message
		logger.debug("Sending a message to queueUrl:[{}].", queueUrl);
		sqs.sendMessage(new SendMessageRequest(queueUrl, msg));
	}

	public void sendMessage(String msg) {
		sendMessage(msg, queueUrl);
	}

	public List<Message> receiveMessages() {
		// Receive messages
		logger.debug("Receiving messages from MyQueue.");
		ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(queueUrl);
		List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages();
		return messages;
	}

}
